<?php

namespace chick1993\util\libs\base;

use Vtiful\Kernel\Excel;

/**
 * @mixin Excel
 * @method array sheetList()
 * @method resource getHandle()
 * @method Excel setRow(string $range, double $height, resource $formatHandler = null);
 * @method Excel setColumn(string $range, double $width, resource $formatHandler = null);
 */
abstract class SheetBase
{
    /**
     * @var string 文件目录
     */
    protected $path;

    /**
     * @var string 文件名
     */
    protected $name;

    /**
     * @var string 文件扩展名
     */
    protected $ext;

    /**
     * @var array 读取文件的验证异常
     */
    protected $rowExceptions;

    protected $mime = [
        'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'csv'  => 'text/csv'
    ];

    /**
     * @var Excel
     */
    protected $excel;
    protected $sheetName;
    protected $skipFlag;

    /**
     * @var array
     */
    protected $format = [];

    /**
     * @var array
     */
    protected $originalFormat = [];

    /**
     * 设置读取时字段的格式，
     * @param array $format ['pay_no' => Excel::TYPE_STRING, 1 => Excel::TYPE_STRING,]
     * @return $this
     */
    public function format(array $format): self
    {
        $this->format = [];
        $this->originalFormat = $format;
        return $this;
    }

    /**
     * 获取读取的格式
     * @return array
     */
    public function getFormat(): array
    {
        return $this->format ?: $this->originalFormat;
    }

    public function __call(string $func, array $args)
    {
        $name = '_' . $func . 'Ex';
        if (method_exists($this, $name)) {
            return call_user_func_array([$this, $name], $args);
        }

        $res = call_user_func_array([$this->excel, $func], $args);
        if ($res instanceof $this->excel) {
            $this->excel = $res;
            return $this;
        } else {
            return $res;
        }
    }

    /**
     * 格式化文件地址信息
     * @param string $filename
     * @return void
     */
    protected function _formatFileInfo(string $filename)
    {
        $this->path = dirname($filename);
        $this->name = basename($filename);
        $this->ext = pathinfo($this->name, PATHINFO_EXTENSION);
    }

    /**
     * 获取读取迭迭代器
     * @param int $start
     * @param int $length
     * @return \Generator
     */
    protected function _getRowIterator(int $start = 0, int $length = 0): \Generator
    {
        $excel = $this->_getReadSheet($start);
        $checkLength = $length > 0;
        $format = $this->getFormat();
        $rowIndex = 0;
        do {
            if ($checkLength && $rowIndex >= $length) break;

            $rowData = $excel->nextRow($format);
            if (is_null($rowData)) break;

            $rowIndex++;
            yield $rowData;
        } while (true);
    }

    /**
     * 获取需要读取的工作表
     * @param int $start 0-第一行
     * @return Excel
     */
    protected function _getReadSheet(int $start = 0): Excel
    {
        $this->excel = $this->excel->openSheet($this->sheetName, $this->skipFlag);
        $start -= 1;
        if ($start >= 0) {
            $this->excel = call_user_func_array([$this->excel, 'setSkipRows'], [$start]);
        }
        return $this->excel;
    }

    protected function _getRowExceptions(): array
    {
        return $this->rowExceptions;
    }
}